#include "cmsis_os.h"
#include "uartPort.h"
#include <stdlib.h>
#include <string.h>
#include "printf.h"
#include "dataProcess.h"
#include "state.h"
#include "ledControl.h"
extern char sprintf_buffer[100];
void output_str(const char* str,uint16_t len);
struct ReadLogParam{
    uint8_t timeEnable:1;//是否输出时间戳
    uint8_t seqEnable:1;//是否输出序号
    uint8_t continueLastEnable:1;//是否从上次结束的地方继续读
    uint8_t startIndexEnable:1;//是否指定了开始索引
    uint8_t numsEnable:1;//是否指定了输出数量
    uint8_t port;
    uint32_t nums;
    uint32_t startIndex;
};
struct ReadLogControl
{
    uint32_t lastIndex[PORT_NUM];//上次读取的最后一个日志的索引
}readLogControl;

uint8_t logParamParse(int argc, char** argv, struct ReadLogParam* param){
    if(argc < 2) return 1;
    param->timeEnable = 0;
    param->seqEnable = 0;
    param->continueLastEnable = 0;
    param->startIndexEnable = 0;
    param->numsEnable = 0;
    param->port = atoi(argv[1]);
    param->nums = UINT32_MAX;
    param->startIndex = 0;

    for(int i=2;i<argc;i++){
        if(strcmp(argv[i],"-time")==0){
            param->timeEnable = 1;
        }
        else if(strcmp(argv[i],"-num")==0){
            if(i+1<argc){
                param->nums = atoi(argv[i+1]);
                param->numsEnable = 1;
                i++;
            }
        }
        else if(strcmp(argv[i],"-start")==0){
            if(i+1<argc){
                param->startIndex = atoi(argv[i+1]);
                param->startIndexEnable = 1;
                i++;
            }
        }
        else if(strcmp(argv[i],"-index")==0){
            param->seqEnable = 1;
        }
        else if(strcmp(argv[i],"-continue")==0){
            param->continueLastEnable = 1;
        }
        else{
            return 1;
        }
    }
    return 0;
}
void cmd_output_str(int argc,char** argv){
    int len;
    int port;
    if(argc <= 1){
        const char put[]="参数错误\r\n";
        output_str(put,sizeof(put));
    }
    else if(argc == 2){//只输入了端口号,输出全部日志
        port = atoi(argv[1]);
        if(port>0&&port<=PORT_NUM){
            uint32_t realOutNums;
            enum State state_bak = state;
            osMutexAcquire(state_mutex,osWaitForever);
            state = STATE_CMD_OUTPUT;
            ledRouse();
            if(state_bak == STATE_RUN) uartPort_stop();
            osMutexRelease(state_mutex);
            frameStrOut(port,0,UINT32_MAX,&realOutNums,0,osWaitForever,output_str);
            len = sprintf(sprintf_buffer,"读取完成，共读取%lu条日志\r\n",realOutNums);
            output_str(sprintf_buffer,len);
            osMutexAcquire(state_mutex,osWaitForever);
            if(state_bak == STATE_RUN) uartPort_start();
            state = state_bak;
            ledRouse();
            osMutexRelease(state_mutex);
        }
        else{
            const char put[]="参数错误\r\n";
            output_str(put,sizeof(put));
        }
    }
    else if(argc>2){
        struct ReadLogParam param;
        if(logParamParse(argc,argv,&param) == 0){
            if(param.port>0&&param.port<=PORT_NUM){
                uint32_t startIndex = 0;
                uint32_t realOutNums;
                if(param.continueLastEnable){
                    startIndex = readLogControl.lastIndex[param.port-1];
                }
                if(param.startIndexEnable){
                    startIndex = param.startIndex;
                }
                enum State state_bak = state;
                osMutexAcquire(state_mutex,osWaitForever);
                state = STATE_CMD_OUTPUT;
                ledRouse();
                if(state_bak == STATE_RUN) uartPort_stop();
                osMutexRelease(state_mutex);
                uint8_t ret = frameStrOut(param.port, startIndex, param.nums, &realOutNums,
                                        (param.timeEnable?0x01:0x00)|(param.seqEnable?0x02:0x00),
                                        osWaitForever, output_str);
                if(ret == 0){
                    readLogControl.lastIndex[param.port-1] = startIndex + realOutNums;
                    len = sprintf(sprintf_buffer,"读取完成，共读取%lu条日志\r\n",realOutNums);
                    output_str(sprintf_buffer,len);
                }
                else if(ret == 1){
                    const char put[]="读取超时\r\n";
                    output_str(put,sizeof(put));
                }
                else if(ret == 2){
                    readLogControl.lastIndex[param.port-1] = startIndex + realOutNums;
                    len = sprintf(sprintf_buffer,"读取完成，共读取%lu条日志\r\n",realOutNums);
                    output_str(sprintf_buffer,len);
                    const char put[]="已经没有数据了\r\n";
                    output_str(put,sizeof(put));
                }
                else if(ret == 3){
                    const char put[]="未知错误\r\n";
                    output_str(put,sizeof(put));
                }
                osMutexAcquire(state_mutex,osWaitForever);
                if(state_bak == STATE_RUN) uartPort_start();
                state = state_bak;
                ledRouse();
                osMutexRelease(state_mutex);
            }
            else{
                const char put[]="参数错误\r\n";
                output_str(put,sizeof(put));
            }
        }
        else{
            const char put[]="参数错误\r\n";
            output_str(put,sizeof(put));
        }
    }
}